/*
package com.ruoyi.web.controller.baodao.task;

import static com.ruoyi.web.controller.baodao.constants.BaodaoConstants.OUTPUT_HLS_PATH;
import static org.bytedeco.ffmpeg.global.avcodec.av_packet_unref;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.web.controller.baodao.constants.BaodaoConstants;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

import java.util.*;

*/
/**
 * @ClassName: HlsPush
 * @Description: hls流切片
 * @author: banmajio
 * @date: 2020-12-11
 *//*

public class VideoPush {

    */
/**
     * @Title: push
     * @Description: hls切片
     * @param input  可以是一个InputStream的流、动态图片(apng,gif等等)，视频文件（mp4,flv,avi等等）,流媒体地址（http-flv,rtmp，rtsp等等）
     * @param output hls切片存放地址
     * @return: void
     * @throws org.bytedeco.javacv.FrameGrabber.Exception
     * @throws org.bytedeco.javacv.FrameRecorder.Exception
     **//*

    public static void push(String input, String output,Thread nowThread)
            throws org.bytedeco.javacv.FrameGrabber.Exception, org.bytedeco.javacv.FrameRecorder.Exception {

        //FFmpegFrameGrabber grabber = null;// 采集器
        CustomFFmpegFrameGrabber grabber = null;// 采集器
        FFmpegFrameRecorder recorder = null;// 解码器

        int bitrate = 2500000;// 比特率
        double framerate;// 帧率
        int err_index = 0;// 推流过程中出现错误的次数
        int timebase;// 时钟基
        long dts = 0, pts = 0;// pkt的dts、pts时间戳
        try {


            // 开启ffmpeg日志级别；QUIET是屏蔽所有，可选INFO、DEBUG、ERROR等
            avutil.av_log_set_level(avutil.AV_LOG_INFO);
            FFmpegLogCallback.set();
            grabber = new CustomFFmpegFrameGrabber(input);
            grabber.start();

            // 异常的framerate，强制使用25帧
            if (grabber.getFrameRate() > 0 && grabber.getFrameRate() < 100) {

                framerate = grabber.getFrameRate();
            } else {

                framerate = 25.0;
            }

            bitrate = grabber.getVideoBitrate();// 获取到的比特率 0
            // 设置采集器构造超时时间(单位微秒，1秒=1000000微秒)
            grabber.setOption("stimeout", "5000000");   //5 秒


            recorder = new FFmpegFrameRecorder(output, grabber.getImageWidth(), grabber.getImageHeight(), 1);
            //recorder = new FFmpegFrameRecorder(output, 1280, 720, 1);
            // 设置比特率
            recorder.setVideoBitrate(bitrate);
            // h264编/解码器
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            // 设置音频编码
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            // 视频帧率(保证视频质量的情况下最低25，低于25会出现闪屏)
            recorder.setFrameRate(framerate);
            // 关键帧间隔，一般与帧率相同或者是视频帧率的两倍
            recorder.setGopSize((int) framerate);
            // 解码器格式
            recorder.setFormat("hls");
            // 单个切片时长,单位是s，默认为2s
            recorder.setOption("hls_time", "60");
            // HLS播放的列表长度，0标识不做限制
            recorder.setOption("hls_list_size", "0");
            // 设置切片的ts文件序号起始值，默认从0开始，可以通过此项更改
            recorder.setOption("start_number", "0");
//			recorder.setOption("hls_segment_type","mpegts");
            // 自动删除切片，如果切片数量大于hls_list_size的数量，则会开始自动删除之前的ts切片，只保 留hls_list_size个数量的切片
            // recorder.setOption("hls_flags","delete_segments");
            // ts切片自动删除阈值，默认值为1，表示早于hls_list_size+1的切片将被删除
            // recorder.setOption("hls_delete_threshold","1");
            */
/*
             * hls的切片类型： 'mpegts'：以MPEG-2传输流格式输出ts切片文件，可以与所有HLS版本兼容。 'fmp4':以Fragmented
             * MP4(简称：fmp4)格式输出切片文件，类似于MPEG-DASH，fmp4文件可用于HLS version 7和更高版本。
             *//*

//			recorder.setOption("hls_segment_type","mpegts");
			//recorder.setOption("hls_segment_type","fmp4");


            AVFormatContext fc = null;
            fc = grabber.getFormatContext();
            recorder.start(fc);
            // 清空探测时留下的缓存
//			grabber.flush();

            AVPacket pkt = null;

            long startTime = System.currentTimeMillis();

            //连续五次没有采集到帧则认为视频采集结束，程序错误次数超过1次即中断程序
            for (int no_pkt_index = 0; no_pkt_index < 5 && err_index < 5;) {
                nowThread.sleep(1); // 用于中断线程时，结束该循环
                pkt = grabber.grabPacket();
                if (pkt == null || pkt.size() <= 0 || pkt.data() == null) {
                    nowThread.sleep(1);
                    no_pkt_index ++;
                    continue;
                }
                // 获取到的pkt的dts，pts异常，将此包丢弃掉。
                if (pkt.dts() == avutil.AV_NOPTS_VALUE && pkt.pts() == avutil.AV_NOPTS_VALUE || pkt.pts() < dts) {

                    err_index ++;
                    av_packet_unref(pkt);
                    continue;
                }
                // 矫正dts，pts
                pkt.pts(pts);
                pkt.dts(dts);
                err_index += (recorder.recordPacket(pkt) ? 0 : 1);
                // pts,dts累加
                timebase = grabber.getFormatContext().streams(pkt.stream_index()).time_base().den();

                pts += (timebase / (int) framerate);
                dts += (timebase / (int) framerate);


                // 更新最后时间
                //videoCache.STARTTIME =  new Date().getTime();;



                // 20分钟后停止录像
                */
/*long videoTS = System.currentTimeMillis() - startTime;
                long seconds = videoTS/ 1000;
                if( seconds > ( 60 * 20 ) ){
                    System.out.println("停止录像");
                    if (recorder != null) {
                        recorder.stop();
                        recorder.release();
                    }
                    grabber.stop();
                    grabber.close();
                }*//*


            }
        } catch (Exception e) {

            grabber.stop();
            grabber.close();
            if (recorder != null) {

                recorder.stop();
                recorder.release();
            }
        } finally {

            grabber.stop();
            grabber.close();
            if (recorder != null) {
                recorder.stop();
                recorder.release();
            }
        }
    }


    public static void liveStartRecord(Thread nowThread){
        // 接口地址
        String apiUrl = RuoYiConfig.getApiurl();
        try {

            // 获取回放视频片段url
            Map<String, String> params = new HashMap<>();
            params.put("sunmi_shop_no", BaodaoConstants.SUNMI_SHOP_NO);    // 对接店铺编号 898250040658
            params.put("ipc_sn", BaodaoConstants.IPC_SN);                       // IPC sn
            String result = HttpUtils.doPost(apiUrl + "/api_sunmi/ipcLiveStart.aspx", params);

            System.out.println("获取直播地址 ipcLiveStart返回值："+result);

            JSONObject ret = JSON.parseObject(result);
            if(ret.getInteger("code").equals(0)){
                //String input = ret.getString("url");
                String input = ret.getString("hls_url");
                String output = OUTPUT_HLS_PATH +System.currentTimeMillis()+"-.m3u8";

                nowThread.sleep(8 * 1000);// 延迟8秒，防止直播流获取不到数据

                System.out.println("开始录制");
                push(input,output,nowThread);
            }
        } catch (Exception ex) {
            System.out.println("liveStartRecord :" + "异常报错");
            System.out.println("liveStartRecord :" + ex);
        }
    }

    // inputFile 输入地址，rtsp/rtmp
    // outputFile 保存文件地址  d:\\1.flv
    // m 秒数
    public static void  frameRecord(String inputFile, String outputFile,Long m) throws Exception{
        boolean isStart = true;
        int bitrate = 2500000;// 比特率
        double framerate;// 帧率

        //创建第一个推流器
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
        grabber.setOption("rtsp_transport","tcp");  // rtsp 默认udp 丢包 改为tcp
        // 增加超时参数
        grabber.setOption("stimeout", "5000000");
        //grabber.setOption(TimeoutOption.STIMEOUT.key(), "5000000");

        // 异常的framerate，强制使用25帧
        if (grabber.getFrameRate() > 0 && grabber.getFrameRate() < 100) {

            framerate = grabber.getFrameRate();
        } else {

            framerate = 25.0;
        }
        bitrate = grabber.getVideoBitrate();// 获取到的比特率 0
        //grabber.setFrameRate(60);           // 帧数
        //grabber.setVideoBitrate(2000000);   // 设置视频编码录音比特率

        // 录制器
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, 1280, 720,1);
        recorder.setFrameRate(framerate);          // 帧数
        recorder.setVideoBitrate(bitrate);  // 设置视频编码录音比特率

        recordByFrame(grabber, recorder, isStart,m);
    }

    private static void recordByFrame(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder, Boolean status,Long m)
            throws Exception{
        try {
            grabber.start();
            recorder.setVideoCodec(grabber.getVideoCodec());
            recorder.start();
            Frame frame = null;
            //计算帧数
            long index=m*25;
            //已经录制帧数
            long finishIndex=0L;
            //Long start=CommonUtil.getSecondTimestamp();
            while (status&& (frame = grabber.grabFrame()) != null) {
                recorder.record(frame);
                finishIndex++;
                //Long end=CommonUtil.getSecondTimestamp();
                if(index<=finishIndex){
                    System.out.println("完成录制");
                    status=false;
                    break;
                }
            }
            recorder.stop();
            grabber.stop();
        } finally {
            if (grabber != null) {
                grabber.stop();
            }
        }
    }



    public static void main(String[] args)
            throws org.bytedeco.javacv.FrameGrabber.Exception, org.bytedeco.javacv.FrameRecorder.Exception, Exception
    {

        //liveStartRecord();


        */
/*push("https://stream-store.sunmi.com:502/live-C20119C200409/1363678639475920896.m3u8?auth_key=1613964898-91213399125790289216338938338106-0-",
                "D:\\profile\\ipc\\"+System.currentTimeMillis()+".m3u8");
*//*

        */
/*frameRecord("https://stream-store.sunmi.com:443/live-C20119C200409/1363657989176692736.flv?auth_key=1613959974-18958506330624629200229378645246-0-",
                "D:\\profile\\hls\\test\\"+System.currentTimeMillis()+".mp4",10L);
*//*

    }

}
*/
